/**
 * @file yfrobot
 * @brief YFROBOT's sensors Mind+ library.
 * @n This is a MindPlus graphics programming extension for YFROBOT's module.
 *
 * @copyright    YFROBOT,2023
 * @copyright    MIT Lesser General Public License
 *
 * @author [email](yfrobot@qq.com)
 * @date  2023-05-19
 */

enum S_H_TYPE {
    //% block="Software"
    Software,
    //% block="Hardware"
    Hardware
}

enum Satellite_DATA_TYPE {
    //% block="location" //位置
    location,
    //% block="date" //日期
    date,
    //% block="time" //时间
    time
}

enum Satellite_DATA {
    //% block="Longitude" //定位-经度
    lng,
    //% block="Latitude" //定位-纬度
    lat,
    //% block="year" //日期-年
    year,
    //% block="month" //日期-月
    month,
    //% block="day" //日期-日
    day,
    //% block="hour" //时间-时
    hour,
    //% block="minute" //时间-分
    minute,
    //% block="second" //时间-秒
    second,
    //% block="centisecond" //时间-厘秒
    centisecond
}

//% color="#92c7f5" iconWidth=40 iconHeight=40
namespace GPS {
    //% block="BDS/GPS [SH] RX[rx]TX[tx] initliallize" blockType="command"
    //% SH.shadow="dropdown" SH.options="S_H_TYPE"
    //% rx.shadow="dropdown" rx.options="SSRXD"
    //% tx.shadow="dropdown" tx.options="SSTXD"
    export function init(parameter: any, block: any) {
        let type_serial = parameter.SH.code;

        Generator.addInclude("include_TinyGPSPlus", `#include <TinyGPSPlus.h>`);
        Generator.addObject("TinyGPSPlus_Object", "TinyGPSPlus", `gps;`);

        if(type_serial === "Software"){ // 软串口
            let rxpin = parameter.rx.code;
            let txpin = parameter.tx.code;
            Generator.addInclude("include_SoftwareSerial", `#include <SoftwareSerial.h>`);
            Generator.addObject("SoftwareSerial_Object", "SoftwareSerial", `GPSSerial(${rxpin}, ${txpin}); // RX, TX`);
            Generator.addDefine("YF_GPS_S", `GPSSerial`);
            Generator.addSetup(`GPS_initSetup`, `YF_GPS_S.begin(9600);`);
        }else if (type_serial === "Hardware"){ // 硬串口
            if(Generator.board === 'arduino'){ // 暂仅支持arduino UNO
                let rxpin = 0;
                let txpin = 1;
                Generator.addDefine("YF_GPS_S", `Serial`);
                Generator.addInclude("include_xxxx", `//硬件串口：RX ${rxpin},TX ${txpin}`);
                Generator.addSetup(`GPS_initSetup`, `YF_GPS_S.begin(9600);`);
            }else if(Generator.board === 'esp32'|| Generator.board === 'firebeetleesp32e'){ // 暂仅支持esp32
                let rxpin = parameter.rx.code;
                let txpin = parameter.tx.code;
                Generator.addDefine("YF_GPS_S", `Serial1`);
                Generator.addInclude("include_xxxx", `//硬件串口：RX ${rxpin},TX ${txpin}`);
                Generator.addSetup(`GPS_initSetup`, `YF_GPS_S.begin(9600,${rxpin},${txpin});`);
            }
        }

    }

    //% block="BDS/GPS get [SDATA] from satellite" blockType="reporter"
    //% SDATA.shadow="dropdown" SDATA.options="Satellite_DATA"
    export function getSatelliteData(parameter: any, block: any) {
        let Data_type = parameter.SDATA.code;
        if (Data_type === `lng` || Data_type === `lat`) {
            Generator.addCode(`gps.location.${Data_type}()`);
        } else if (Data_type === `year` || Data_type === `month` || Data_type === `day`) {
            Generator.addCode(`gps.date.${Data_type}()`);
        } else if (Data_type === `hour` || Data_type === `minute` || Data_type === `second` || Data_type === `centisecond`) {
            Generator.addCode(`gps.time.${Data_type}()`);
        } else if (Data_type === `date`) {
            Generator.addCode(`gps.${Data_type}()`);
        } else if (Data_type === `time`) {
            Generator.addCode(`gps.${Data_type}()`);
        }
    }

    //% block="Is BDS/GPS get Data?" blockType="boolean"
    export function isgetSatelliteData(parameter: any, block: any) {
        Generator.addCode(`YF_GPS_S.available()`);
    }

    //% block="Parsing Data Success" blockType="command"
    export function ParsingSatelliteData(parameter: any, block: any) {
        Generator.addCode(`gps.encode(YF_GPS_S.read());`);
    }

    //% block="Is [SDATA_T] Valid?" blockType="boolean"
    //% SDATA_T.shadow="dropdown" SDATA_T.options="Satellite_DATA_TYPE"
    export function isDataValid(parameter: any, block: any) {
        let Data_type = parameter.SDATA_T.code;
        Generator.addCode(`gps.${Data_type}.isValid()`);
    }
    //% block="prohibit beidou positioning module" blockType="command"
    export function SerialEnd(parameter: any, block: any) {
        Generator.addCode(`YF_GPS_S.end();`);
    }
}
